/*
 * @(#)AbstractFunctionAccessAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.user.web;

import java.sql.Connection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionMapping;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.PermissionManager;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.AbstractPermissionObject;
import com.dcivision.framework.dao.AbstractDAObject;
import com.dcivision.framework.web.AbstractActionForm;
import com.dcivision.framework.web.AbstractMaintAction;
import com.dcivision.user.bean.UserGroupPermission;
import com.dcivision.user.bean.UserRecordPermission;
import com.dcivision.user.bean.UserRolePermission;
import com.dcivision.user.dao.UserGroupPermissionDAObject;
import com.dcivision.user.dao.UserRecordPermissionDAObject;
import com.dcivision.user.dao.UserRolePermissionDAObject;

/**
  AbstractFunctionAccessAction.java

  This class is for maint function access by mean of role, group and user.

    @author          Phoebe Wong
    @company         DCIVision Limited
    @creation date   24/07/2003
    @version         $Revision: 1.12 $
*/

public abstract class AbstractFunctionAccessAction extends AbstractMaintAction {
  protected String objectIDProperty = "ID";

  public AbstractFunctionAccessAction() {
    super();
  }

  public String getSubjectType() {
    return(GlobalConstant.SUBJECT_TYPE_ROLE);
  }

  protected Integer getObjectID(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    String objectIDStr = null;
    try {
      objectIDStr = org.apache.commons.beanutils.BeanUtils.getProperty(form, this.objectIDProperty);
    } catch (Exception e) {
      log.error("Cannot get the object ID field.", e);
      return(null);
    }
    Integer objectID = TextUtility.parseIntegerObj(objectIDStr);
    return(objectID);
  }

  public void retrievePermission(AbstractActionForm form, List result) throws ApplicationException {
    StringBuffer sbPermission = new StringBuffer();
    for (int i = 0; i < result.size(); i++) {
      AbstractPermissionObject permObj = (AbstractPermissionObject)result.get(i);
      if (GlobalConstant.NAV_MODE_CHANGE.equals(form.getNavMode())) {
        sbPermission.append("-1\t");
      } else {
        sbPermission.append(permObj.getID() + "\t");
      }
      sbPermission.append(permObj.getObjectID() + "\t");
      sbPermission.append(permObj.getPermission() + "\t");
      sbPermission.append(TextUtility.formatDate(permObj.getStartTime(), SystemParameterFactory.getSystemParameter(SystemParameterConstant.DB_DATETIME_FORMAT)) + "\t");
      sbPermission.append(TextUtility.formatDate(permObj.getEndTime(), SystemParameterFactory.getSystemParameter(SystemParameterConstant.DB_DATETIME_FORMAT)) + "\n");
    }
    ((AbstractFunctionAccessForm)form).setFunctionPermission(sbPermission.toString());
  }

  public void updatePermissionObjects(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    
    //update all sessionctn permission string in cache
    PermissionManager.fireSystemFunctionPermissionChanged();       
    
    SessionContainer sessionContainer = this.getSessionContainer(request);
    Connection connection = this.getConnection(request);
    String subjectType = this.getSubjectType();
    
    updatePermissionObjectsNoRequest(form, sessionContainer, connection, subjectType);
  }
/**
 * update permission from object(role or group or user ),but no need request parameter
 * @param form
 * @param functionPermission
 * @param sessionContainer
 * @param connection
 * @param subjectType
 * @throws ApplicationException
 */
  public void updatePermissionObjectsNoRequest(AbstractActionForm form,  SessionContainer sessionContainer, Connection connection, String subjectType) throws ApplicationException {
    String functionPermission = ((AbstractFunctionAccessForm)form).getFunctionPermission();
    String permData = TextUtility.replaceString(functionPermission, "\r", "");
    String[] tmpAry = TextUtility.splitString(permData, "\n");
    if (Utility.isEmpty(tmpAry)) {
      tmpAry = new String[0];
    }
    
    AbstractDAObject dao = null;
    if (GlobalConstant.SUBJECT_TYPE_ROLE.equals(subjectType)) {
      dao = new UserRolePermissionDAObject(sessionContainer, connection);
    } else if (GlobalConstant.SUBJECT_TYPE_GROUP.equals(subjectType)) {
      dao = new UserGroupPermissionDAObject(sessionContainer, connection);
    } else if (GlobalConstant.SUBJECT_TYPE_USER.equals(subjectType)) {
      dao = new UserRecordPermissionDAObject(sessionContainer, connection);
    }

    // Delete those permission which should not existed anymore.
    List existingIDs = new java.util.ArrayList();
    for (int i = 0; i < tmpAry.length; i++) {
      if (!Utility.isEmpty(tmpAry[i])) {
        String[] rowAry = TextUtility.splitString(tmpAry[i], "\t");
        existingIDs.add(rowAry[0]);
      }
    }

    final Integer formID = new Integer(form.getID());
    if (GlobalConstant.SUBJECT_TYPE_ROLE.equals(subjectType)) {
      ((UserRolePermissionDAObject)dao).deleteListByObjectTypeUserRoleID(GlobalConstant.OBJECT_TYPE_FUNCTION, formID, existingIDs);
    } else if (GlobalConstant.SUBJECT_TYPE_GROUP.equals(subjectType)) {
      ((UserGroupPermissionDAObject)dao).deleteListByObjectTypeUserGroupID(GlobalConstant.OBJECT_TYPE_FUNCTION, formID, existingIDs);
    } else if (GlobalConstant.SUBJECT_TYPE_USER.equals(subjectType)) {
      ((UserRecordPermissionDAObject)dao).deleteListByObjectTypeUserRecordID(GlobalConstant.OBJECT_TYPE_FUNCTION, formID, existingIDs);
    }

    // Insert or update permission records.
    for (int i = 0; i < tmpAry.length; i++) {
      if (!Utility.isEmpty(tmpAry[i])) {
        String[] rowAry = TextUtility.splitString(tmpAry[i], "\t");

        AbstractPermissionObject permObj = null;
        if (GlobalConstant.SUBJECT_TYPE_ROLE.equals(subjectType)) {
          permObj = new UserRolePermission();
          ((UserRolePermission)permObj).setUserRoleID(formID);
        } else if (GlobalConstant.SUBJECT_TYPE_GROUP.equals(subjectType)) {
          permObj = new UserGroupPermission();
          ((UserGroupPermission)permObj).setUserGroupID(formID);
        } else if (GlobalConstant.SUBJECT_TYPE_USER.equals(subjectType)) {
          permObj = new UserRecordPermission();
          ((UserRecordPermission)permObj).setUserRecordID(formID);
        }

        // Form a bean.
        permObj.setID(new Integer(rowAry[0]));
        permObj.setObjectType(GlobalConstant.OBJECT_TYPE_FUNCTION);
        permObj.setObjectID(new Integer(rowAry[1]));
        permObj.setPermission(rowAry[2]);
        if (rowAry.length>3) {
          permObj.setStartTime(form.parseTimestamp(rowAry[3]));
        }
        if (rowAry.length>4) {
          permObj.setEndTime(form.parseTimestamp(rowAry[4]));
        }
        permObj.setUpdateCount(new Integer(0));

        if ("-1".equals(rowAry[0])) {
          dao.insertObject(permObj);
        } else {
          dao.updateObject(permObj);
        }       
      }  
    }
  }

  /**
   * selectRecord
   *
   * @param mapping
   * @param form
   * @param request
   * @param response
   * @throws ApplicationException
   */
  public void selectRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    super.selectRecord(mapping, form, request, response);
    List result = null;

    if (GlobalConstant.SUBJECT_TYPE_ROLE.equals(this.getSubjectType())) {
      UserRolePermissionDAObject userRoleDAO = new UserRolePermissionDAObject(this.getSessionContainer(request), this.getConnection(request));
      result = userRoleDAO.getListByUserRoleIDObjectType(new Integer(form.getID()), GlobalConstant.OBJECT_TYPE_FUNCTION);
    } else if (GlobalConstant.SUBJECT_TYPE_GROUP.equals(this.getSubjectType())) {
      UserGroupPermissionDAObject userGroupDAO = new UserGroupPermissionDAObject(this.getSessionContainer(request), this.getConnection(request));
      result = userGroupDAO.getListByUserGroupIDObjectType(new Integer(form.getID()), GlobalConstant.OBJECT_TYPE_FUNCTION);
    } else if (GlobalConstant.SUBJECT_TYPE_USER.equals(this.getSubjectType())) {
      UserRecordPermissionDAObject userRecordDAO = new UserRecordPermissionDAObject(this.getSessionContainer(request), this.getConnection(request));
      result = userRecordDAO.getListByUserRecordIDObjectType(new Integer(form.getID()), GlobalConstant.OBJECT_TYPE_FUNCTION);
    }

    retrievePermission(form, result);
  }

  public void insertRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    super.insertRecord(mapping, form, request, response);
    this.updatePermissionObjects(mapping, form, request, response);
  }

  public void updateRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    super.updateRecord(mapping, form, request, response);
    this.updatePermissionObjects(mapping, form, request, response);
  }

}